/***
 * 脚本依赖;
 * common.js
 * ejs.js
 * $,jQuery
 *
 */
(function ($) {
    var $Table = {
        tableSelect: function ($table, destroyBtn, createBtn, options) {
            $table.find('tbody tr').unbind('click').click(function () {
                if ($(this).text() && $(this).text().indexOf('没有找到符合查询条件的数据!') > -1) {
                    searchInputValue('search'); //
                    return;
                }
                if ($(this).hasClass('active')) {
                    destroyBtn && destroyBtn();
                    $(this).removeClass('active').find('td:first-child input[type=checkbox]').attr('checked', false).prop('checked', false);
                } else {
                    if ($(this).data('json')) {
                        createBtn && createBtn(this);
                        var $checkbox = $(this).addClass('active').find('td:first-child input[type=checkbox]');
                        if ($checkbox.length) {
                            $checkbox.attr('checked', true).prop('checked', true);
                            if (!options.multiSelect) { // 单选
                                $checkbox.closest('tr').siblings('tr').removeClass('active').find('td:first-child input[type=checkbox]').attr('checked', false).prop('checked', false);
                            }
                        } else {
                            $(this).addClass('active');
                            if (!options.multiSelect) { // 单选
                                $(this).closest('tr').siblings('tr').removeClass('active').find('td:first-child input[type=checkbox]').attr('checked', false).prop('checked', false);
                            }
                        }
                    }
                }
            })
        },
        'sort': function ($table, search) {
            $table.find('th .fa').unbind('click').click(function (e) {
                var sort = {sortField: '', sortOrder: ''};
                sort.sortField = $(this).data('sort');
                if ($(this).hasClass('fa-sort') || $(this).hasClass('fa-sort-desc')) {
                    sort.sortOrder = 'ASC';
                    $(this)
                        .removeClass('fa-sort-desc fa-sort')
                        .addClass('fa-sort-asc');
                    $(this)
                        .closest('th')
                        .siblings('th')
                        .find('.fa')
                        .removeClass('fa-sort-desc fa-sort-asc')
                        .addClass('fa-sort');
                } else if ($(this).hasClass('fa-sort-asc')) { //asc
                    sort.sortOrder = 'DESC';
                    $(this)
                        .removeClass('fa-sort-asc fa-sort')
                        .addClass('fa-sort-desc');
                    $(this)
                        .closest('th')
                        .siblings('th')
                        .find('.fa')
                        .removeClass('fa-sort-desc fa-sort-asc')
                        .addClass('fa-sort')
                }
                search && search(sort);
            })

        },
        initThead: function () {
            var $tr_ = $('<tr></tr>');
            options.fields.forEach(function (item, index1) {
                if (index1 == 0) {
                    if (options.checkbox || options.radio) {
                        $tr_.append($('<th></th>'));
                    }
                    if (options.seqNum) {
                        $tr_.append($('<th>序号</th>').css({width: 35}));
                    }
                }
                var $th = $('<th>' + item.label + '</th>');
                if (item.enableSort) {
                    $th.append($('<i data-sort="name" class="pull-right fa fa-sort"></i>'));
                }
                $tr_.append($th);
            });

        },
        /***
         * 初始化搜索框
         */
        initSearch: function (options) {
            if ($('input.search').length) {
                return false;
            }
            //basic search
            var $searchType = $('<div class="input-group-btn"></div>'),
                $searchTypeDown = $('<ul class="dropdown-menu" role="menu"></ul>'),
                $searchTypeLabel = $('<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false">单位名称 <span class="caret"></span></button>'),
                $searchInput = $('<input type="text" class="form-control search" data-toggle="autocomplete" data-lookup="[&quot;aaa&quot;, &quot;bbb&quot;, &quot;ccc&quot;, &quot;ddd&quot;, &quot;edfa&quot;, &quot;wdasda&quot;, &quot;tueiyhgk&quot;, &quot;vjflcjx&quot;]" placeholder="请输入...">'),
                $searchBtn = $('<span class="input-group-btn"><button class="btn btn-primary search-btn" data-loading-text="查询中..." type="button">查询</button></span>'),
                $searchCtner = $('<div class="input-group pull-left" style="width: 350px;"></div>');
            var $searchSenior = $('<div class="search-senior"></div>'),
                $searchFormInline = $('<div class="form-inline"></div>'),
                length = 0;
            options.fields.forEach(function (item, index) {
                if (item.enableSearch) {
                    length++;
                    var $item = $('<li><a href="#">' + item.label + '</a></li>');
                    var $seniorItem = '';
                    if (item.dateRange) { //日期范围搜索
                        $seniorItem = $('<div class="form-group input-daterange" data-toggle="datepicker" data-date-start-date="' + (item.start || '2017-03-01') + '"' +
                            ' data-date-end-date="' + ((item.end || moment(Date.now()).format('YYYY-MM-DD'))) + '"><label class="sr-only">' + item.label + ':</label>' +
                            '<input type="text" name="' + item.name + 'Start" data-date-size="small" readonly="readonly" class="form-control input-date"' +
                            ' placeholder="' + item.label + '开始日期"' +
                            ' style="width: 125px;">-<input  name="' + item.name + 'End"  readonly="readonly"  data-date-size="small" type="text" class="form-control input-date" ' +
                            ' style="width: 125px;" placeholder="' + item.label + '结束日期" >');
                    } else {
                        $seniorItem = $('<div class="form-group"><label class="sr-only"></label>' +
                            '<input type="text" class="form-control" name="' + item.name + '" placeholder="' + item.label + '">&nbsp;</div>');
                        $seniorItem = $('<div class="form-group ><label class="sr-only"></label>' +
                            '<input type="text" class="form-control" name="' + item.name + '" placeholder="' + item.label + '">&nbsp;</div>');
                    }
                    $item.data('json', item);
                    $searchTypeDown.append($item);
                    $searchFormInline.append($seniorItem.css({margin: '0 5px 11px 0'}));
                    $item.unbind('click').click(function () {
                        var $data = $(this).data('json');
                        $searchTypeLabel.html($data.label + ' <span class="caret"></span>').data('json', $data);
                    });
                    if (!$searchTypeLabel.data('json')) { // 未初始化
                        $searchTypeLabel.html(item.label + ' <span class="caret"></span>').data('json', item)
                    }
                }
                if (item.enableFilter) {
                    length++;
                    var $item = $('<li><a href="#">' + item.label + '</a></li>');
                    var $seniorItem = $('<div class="form-group"><label class="sr-only">' + item.label + '：</label>' +
                        '<select type="text" class="form-control" name="' + item.name + '" placeholder="' + item.label + '">' +
                        item.filters.map(function (item) {
                            return '<option value="' + item.value + '">' + item.label + '</option>';
                        }).join('') +
                        '</select></div>');

                    $item.data('json', item);
                    $searchTypeDown.append($item);
                    $searchFormInline.append($seniorItem.css({margin: '0 5px 11px 0'}));
                }
            });
            if (length == 0)return;
            $searchType.append($searchTypeLabel).append($searchTypeDown);
            if (options.complexItems && options.showSearchComplex) {
                options.complexItems.forEach(function (item) {
                    var $seniorItem = '';
                    if (item.dateRange) { //日期范围搜索
                        $seniorItem = $('<div class="form-group input-daterange" data-toggle="datepicker" data-date-start-date="' + (item.start || '2017-03-01') + '"' +
                            ' data-date-end-date="' + ((item.end || moment(Date.now()).format('YYYY-MM-DD'))) + '"><label class="sr-only">' + item.label + ':</label>' +
                            '<input type="text" name="' + item.name + 'Start" data-date-size="small" class="form-control input-date"' +
                            ' placeholder="' + item.label + '开始日期"' +
                            ' style="width: 125px;">-<input  name="' + item.name + 'End"  data-date-size="small" type="text" class="form-control input-date" ' +
                            ' style="width: 125px;" placeholder="' + item.label + '结束日期" />&nbsp;');
                    } else {
                        $seniorItem = $('<div class="form-group"><label class="sr-only">' + item.label + '：</label>' +
                            '<input type="text" class="form-control" name="' + item.name + '" placeholder="' + item.label + '">&nbsp;</div>');
                        $seniorItem = $('<div class="form-group ><label class="sr-only">' + item.label + '：</label>' +
                            '<input type="text" class="form-control" name="' + item.name + '" placeholder="' + item.label + '">&nbsp;</div>');
                    }
                    $searchFormInline.append($seniorItem.css({marginBottom: '10px'}));
                })
            }
            $searchBtn.unbind('click').click(function () { // 单项搜索
                var $data = $searchTypeLabel.data('json');
                var obj = {};
                var $lis = $(this).closest('.input-group').find('li');
                $lis.each(function () {
                    var $json = $(this).data('json');
                    obj[$json.name] = ""; // 单项搜索时，过滤非当前项条件干扰
                });
                obj[$data.name] = $searchInput.val();
                obj.page = 1;
                options.search && options.search(obj)
            });

            $searchCtner.append($searchType).append($searchInput).append($searchBtn);

            var $searchSwitch = $('<a class="search-switch pull-left">高级搜索</a>'),
                $search = $('<button type="submit" class="btn btn-primary">搜索</button>'),
                $export = $('<button type="submit" class="btn btn-primary export">导出</button>');
            $searchFormInline.append($search.css({margin: '0 5px 11px 0'}));
            $search.unbind('click').click(function () { // 高级搜索
                var search = {};
                $(this).siblings('.form-group').find('input,select').each(function (index, item) {
                    search[item.name] = item.value;
                });
                options.search && options.search(search)
            });
            $searchSenior.hide();
            $searchSenior.append($searchFormInline);
            $searchSwitch.unbind('click').click(function () {
                if ($(this).text().indexOf('高级') > -1) {
                    $(this).text('普通搜索');
                    $searchCtner.hide();
                    $searchSenior.show();
                    $searchSenior.find('input[name=' + $searchTypeLabel.data('json')['name'] + ']').val($searchInput.val())
                } else {
                    $searchCtner.show();
                    $searchSenior.hide();
                    $searchInput.val($searchSenior.find('input[name=' + $searchTypeLabel.data('json')['name'] + ']').val());
                    // $searchSenior.find('input[name='+$searchTypeLabel.data('json')['name']+']').val($searchInput.val())
                    $(this).text('高级搜索')
                }
            });

            $searchSenior.css({padding: '12px 12px 0'});
            $searchFormInline.css({paddingBottom: '0px'});
            $(options.toolbar).find('.pull-right').append($searchCtner);
            if (length > 1 || options.showSearchComplex) {
                $(options.toolbar).find('.pull-right').append($searchSwitch);
                if (options.showSearchComplex) {
                    $searchSwitch.click().hide();
                }
            }
            if (options.export) {
                var date = new Date();
                $searchFormInline.find('[name=dateStart]').val(getMonthBeginAndEnd().start);
                $searchFormInline.find('[name=dateEnd]').val(getMonthBeginAndEnd().end);
                $export.unbind('click').click(function () {
                    if (options.search) {
                        var search = {};
                        $(this).siblings('.form-group').find('input,select').each(function (index, item) {
                            search[item.name] = item.value;
                        });
                        generateExportUrl(options.search({}, true, true));
                    }
                });
                $searchFormInline.append($export.css({margin: '0 5px 11px 0'}));
            }
            $searchFormInline.find('input[type=text]').unbind('keydown').keydown(function (e) { // 高级搜索
                if (e.keyCode == 13) {
                    $search.click();
                }
            });
            $searchCtner.find('input[type=text]').unbind('keydown').keydown(function (e) { // 高级搜索
                if (e.keyCode == 13) {
                    $searchBtn.click();
                }
            });
            $searchSenior.insertBefore($(options.toolbar).closest('.panel-body'));
        },
        initTbody: function (options) {

        },
        initCellData: function (item, rowData, index1, dataArray, options) {
            return (!!item.filter ? item.filter(rowData, dataArray) : ((rowData[options.fields[index1].name] != 0) ? (rowData[options.fields[index1].name] || '-') : rowData[options.fields[index1].name]))
        },
        initCustomColumn: function (options) {
            if ($('[multiple="multiple"]').length)return;
            if (options.fields.length < 5)return;
            var $multiEle = $('<select data-placeholder="自定义列" multiple="multiple"></select>');
            $(options.toolbar).find('.pull-right').append($multiEle);
            var $multi = $multiEle.multiselect($.extend(MULTI_SETTING, {
                onDropdownHide: function (event) {
                    // console.log($multi.multiselect('getSelected'))
                },
                onChange: function (option, selected) {
                    if (!selected) {
                        $('.custom-' + $(option).val()).hide()
                    } else {
                        $('.custom-' + $(option).val()).show()
                    }
                    // console.log($multiEle.val());
                    $.post('/user/setting', {
                        module: window.location.pathname,
                        columns: $multiEle.val().join(',')
                    })
                },
                // onDeselectAll: function() {
                //     alert('onDeselectAll triggered!');
                // }
            }));
            $.post('/user/getSetting', {
                module: window.location.pathname,
            }, function (item_) {
                if (!item_.data) {
                    var options_ = options.fields.map(function (item) {
                        item.value = item.name;
                        item.selected = true;
                        return item;
                    });
                    $multi.multiselect('dataprovider', options_);
                } else {
                    var options_ = options.fields.map(function (item) {
                        item.value = item.name;
                        if (item_.data.columns) {
                            // item_.data.columns = item_.data.columns;
                            if (item_.data.columns.indexOf(item.name) > -1) {
                                item.selected = true;
                                $('.custom-' + item.name).show()

                            } else {
                                item.selected = false;
                                $('.custom-' + item.name).hide()
                            }
                        } else {
                            item.selected = false;
                        }
                        return item;
                    });
                    $multi.multiselect('dataprovider', options_);
                }
            });
        },
        initRowHead: function (options, $tr, length, index) {
            var rs = length ==0?'':('rowspan="'+rs+'"');
            if (options.checkbox) {
                $tr.append($('<td class="vm" rs ><input type="checkbox"/></th>'));
            }
            if (options.radio) {
                $tr.append($('<td class="vm" rs><input type="radio" name="radio"/></th>'));
            }
            if (options.seqNum) {
                $tr.append($('<td class="vm" rs>' + (index + 1) + '</th>'));
            }
            return $tr;
        },
        init: function (options) {
            var $table = $(this);
            initSubPageScroll();
            var $tr_ = $('<tr></tr>'),
                $thead = $('<thead></thead>'),
                $tbody = $('<tbody></tbody>');
            if (options.data.length == 0) {
                $table.find('tbody').html(noData());
            }
            var $trTotal_ = $('<tr></tr>'), total_ = {};
            if((typeof options.data) == 'string'){
                $("tbody").append(options.data)
            }else{
                options.data.forEach(function (obj, index) {
                    if (obj instanceof Array && obj.length > 1) {
                        obj = _.sortBy(obj, 'id');
                        obj.map(function (subDataRow, subDataIndex) {
                            var $tr = $('<tr></tr>');

                            options.fields.forEach(function (item, index1) {
                                var $td = $('<td></td>');
                                console.log(item);
                                item.style && $td.attr('style', item.style);

                                if (item.fnStyle) {
                                    if (typeof item.fnStyle == "function") {
                                        $td.attr('style', item.fnStyle(obj));
                                    }
                                }
                                $td.addClass('custom-' + item.name);
                                if (index == 0 && subDataIndex == 0) {
                                    if (index1 == 0) {
                                        if (options.checkbox) {
                                            $tr_.append($('<th></th>'));
                                        }
                                        if (options.seqNum) {
                                            $tr_.append($('<th>序号</th>').css({
                                                width: 40,
                                                marginRight: '7px',
                                                'fontSize': '10px'
                                            }));
                                        }

                                        $trTotal_.append($('<td>合计</td>'));
                                    }
                                    if (item.total) { // 合计
                                        $trTotal_.append('<td class="total-' + item.name + '"></td>')
                                    } else {
                                        $trTotal_.append('<td></td>')
                                    }
                                    var $th = $('<th>' + item.label + '</th>');
                                    $th.addClass('custom-' + item.name);
                                    if (item.enableSort) {
                                        $th.append($('<i data-sort="' + item._sort + '" class="pull-right fa fa-sort"></i>'));
                                    }
                                    $tr_.append($th);
                                }

                                if ($('th.custom-' + item.name).length && $('th.custom-' + item.name).css('display') == 'none') {
                                    $td.hide()
                                }
                                if (subDataIndex == 0) {
                                    if (item.combine) {
                                        if (index1 == 0) {
                                            $tr = $Table.initRowHead(options, $tr, obj.length, index);
                                        }
                                        $td.html($Table.initCellData(item, subDataRow, index1, obj, options));
                                        $td.addClass('vm');
                                        if(obj.length!=0){
                                            $td.attr('rowspan', obj.length)
                                        }
                                    } else {
                                        $td.html($Table.initCellData(item, subDataRow, index1, null, options));
                                    }
                                    $tr.append($td)
                                } else if (subDataIndex != 0 && !item.combine) {
                                    $td.html($Table.initCellData(item, subDataRow, index1, null, options));
                                    if ($tr.find('td').length == 0) $td.css({
                                        borderLeft: '1px solid #dddddd',
                                        textAlign: "left"
                                    });
                                    $tr.append($td);
                                }
                            });
                            if (!subDataIndex) {
                                $tr.data('json', subDataRow).attr('id', subDataRow.id);
                            }
                            $tbody.append($tr);
                        });

                    } else {
                        if (obj instanceof Array) {
                            obj = obj[0];
                        }
                        var $tr = $('<tr></tr>');
                        options.fields.forEach(function (item, index1) {
                            var $td = $('<td  style="' + (item.style || '') + '" >' + (!!item.filter ? item.filter(obj) : ((obj[options.fields[index1].name] != 0) ? (obj[options.fields[index1].name] || '-') : obj[options.fields[index1].name])) + '</td>');
                            if (item.fnStyle) {
                                if (typeof item.fnStyle == "function") {
                                    $td.attr('style', item.fnStyle(obj));
                                }
                            }
                            if (item.total) {
                                if (Object.keys(total_).length == 0) {
                                    total_['initValue'] = item.initValue || 0;
                                }
                                if (total_[item.name]) {
                                    total_[item.name] = floatTool.add(total_[item.name] || 0, item.filter(obj));
                                } else {
                                    total_[item.name] = item.filter(obj);
                                }
                            }
                            if (item.filterAsync) {
                                item.filterAsync(obj, $td);
                            }
                            if (index1 == 0) {
                                $tr = $Table.initRowHead(options, $tr, 0, index);
                            }
                            if (index == 0) {
                                if (index1 == 0) {
                                    if (options.checkbox) {
                                        $tr_.append($('<th></th>'));
                                    }
                                    if (options.seqNum) {
                                        $tr_.append($('<th>序号</th>').css({
                                            width: 40,
                                            marginRight: '7px',
                                            'fontSize': '10px'
                                        }));
                                    }

                                    $trTotal_.append($('<td>合计</td>'));
                                }
                                if (item.total) { // 合计
                                    $trTotal_.append('<td class="total-' + item.name + '"></td>')
                                } else {
                                    $trTotal_.append('<td></td>')
                                }
                                var $th = $('<th>' + item.label + '</th>');
                                $th.addClass('custom-' + item.name);
                                if (item.enableSort) {
                                    $th.append($('<i data-sort="' + item._sort + '" class="pull-right fa fa-sort"></i>'));
                                }
                                $tr_.append($th);
                            }
                            $td.addClass('custom-' + item.name);
                            if ($('th.custom-' + item.name).length && $('th.custom-' + item.name).css('display') == 'none') {
                                $td.hide()
                            }
                            $tr.append($td)
                        });
                        $tr.data('json', obj).attr('id', obj.id);
                        $tbody.append($tr);
                    }

                });
                if (Object.keys(total_).length > 0) {
                    Object.keys(total_).map(function (key) {
                        $trTotal_.find('.total-' + key).html(total_[key]);
                        $tbody.append($trTotal_)
                    })
                }
                if ($table.hasClass('sticky-thead')) {
                    return;
                }
                if ($table.data('$table') && $table.find('th').length) {
                    $table.find('tbody').replaceWith($tbody);
                } else {
                    $table.data('$table', $table);
                    $Table.initSearch(options);
                    $Table.initCustomColumn(options);
                    if (options.onlyBody) {
                        $table.find('tbody').replaceWith(options.data.length == 0 ? noData($tr_.find('th:visible').length || 1) : $tbody);
                    } else {
                        $table.html('').append($thead.append($tr_)).append(options.data.length == 0 ? noData($tr_.find('th:visible').length || 1) : $tbody);
                    }
                    $Table.sort($table, options.sort);

                }
                if ($table.data('$table') && $table.find('th').length && options.fixedHeader) {
                    // fixedTableHeader();
                }

                // $Table.tableSelect($table, options.destroyBtn, options.createBtn,options); //removed at 2017-06-12
                if (options.rendered) {
                    options.rendered && options.rendered();
                }
                searchInputValue('search');

                if (!options.removeLineSelected) {
                    $Table.tableSelect($table, options.destroyBtn, options.createBtn, options);
                }

            }

            // $table.fixedHeaderTable({height: '400', altClass: 'odd', themeClass: 'fancyDarkTable'});
        },
        show: function () {
            // is
        },
        hide: function () {
            // good
        },
        update: function (content) {
            // !!!
        }
    };
    $.fn.$table = function (options) {
        var _default = {
            fields: []
            // 'location': 'top',
            // 'background-color': 'blue'
        };
        options = $.extend({}, _default, options || {});
        if (!$.isArray(options.fields) || !options.fields.length) {
            throw new Error('option.field must be array and option.field.length must over 0 !')
        }
        return this.each(function () {
            $Table.init.call(this, options);
        })
    };
})(jQuery);


function fixedTableHeader() {
    if ($('body').find('.sticky-thead').length) { //一个页面初始化一个sticky-header
        return;
    }
    $('table').each(function () {
        if ($(this).find('thead').length > 0 && $(this).find('th').length > 0) {
            // Clone <thead>
            var $w = $(window),
                $t = $(this),
                $thead = $t.find('thead').clone(),
                $col = $t.find('thead, tbody').clone();

            // Add class, remove margins, reset width and wrap table
            $t
                .addClass('sticky-enabled')
                .css({
                    margin: 0,
                    width: '100%'
                }).wrap('<div class="sticky-wrap" />');

            if ($t.hasClass('overflow-y')) $t.removeClass('overflow-y').parent().addClass('overflow-y');

            // Create new sticky table head (basic)
            $t.after('<table class="sticky-thead table table-bordered" />');

            // If <tbody> contains <th>, then we create sticky column and intersect (advanced)
            if ($t.find('tbody th').length > 0) {
                $t.after('<table class="sticky-col" /><table class="sticky-intersect" />');
            }

            // Create shorthand for things
            var $stickyHead = $(this).siblings('.sticky-thead'),
                $stickyCol = $(this).siblings('.sticky-col'),
                $stickyInsct = $(this).siblings('.sticky-intersect'),
                $stickyWrap = $(this).parent('.sticky-wrap');

            $stickyHead.append($thead);

            $stickyCol
                .append($col)
                .find('thead th:gt(0)').remove()
                .end()
                .find('tbody td').remove();

            $stickyInsct.html('<thead><tr><th>' + $t.find('thead th:first-child').html() + '</th></tr></thead>');

            // Set widths
            var setWidths = function () {
                    $t
                        .find('thead th').each(function (i) {
                        $stickyHead.find('th').eq(i).width($(this).width());
                    })
                        .end()
                        .find('tr').each(function (i) {
                        $stickyCol.find('tr').eq(i).height($(this).height());
                    });

                    // Set width of sticky table head
                    $stickyHead.width($t.width());

                    // Set width of sticky table col
                    $stickyCol.find('th').add($stickyInsct.find('th')).width($t.find('thead th').width())
                },
                repositionStickyHead = function () {
                    // Return value of calculated allowance
                    var allowance = calcAllowance();

                    // Check if wrapper parent is overflowing along the y-axis
                    if ($t.height() > $stickyWrap.height()) {
                        // If it is overflowing (advanced layout)
                        // Position sticky header based on wrapper scrollTop()
                        if ($stickyWrap.scrollTop() > 0) {
                            // When top of wrapping parent is out of view
                            $stickyHead.add($stickyInsct).css({
                                opacity: 1, display: 'block',
                                top: $stickyWrap.scrollTop()
                            });
                        } else {
                            // When top of wrapping parent is in view
                            $stickyHead.add($stickyInsct).css({
                                opacity: 0, display: 'none',
                                top: 0
                            });
                        }
                    } else {
                        // If it is not overflowing (basic layout)
                        // Position sticky header based on viewport scrollTop
                        if ($w.scrollTop() > $t.offset().top && $w.scrollTop() < $t.offset().top + $t.outerHeight() - allowance) {
                            // When top of viewport is in the table itself
                            $stickyHead.add($stickyInsct).css({
                                opacity: 1,
                                display: 'block',
                                top: $w.scrollTop() - $t.offset().top + 45
                            });
                        } else {
                            // When top of viewport is above or below table
                            $stickyHead.add($stickyInsct).css({
                                opacity: 0, display: 'none',
                                top: 45
                            });
                        }
                    }
                },
                repositionStickyCol = function () {
                    if ($stickyWrap.scrollLeft() > 0) {
                        // When left of wrapping parent is out of view
                        $stickyCol.add($stickyInsct).css({
                            opacity: 1, display: 'block',
                            left: $stickyWrap.scrollLeft()
                        });
                    } else {
                        // When left of wrapping parent is in view
                        $stickyCol
                            .css({opacity: 0, display: 'none'})
                            .add($stickyInsct).css({left: 0});
                    }
                },
                calcAllowance = function () {
                    var a = 0;
                    // Calculate allowance
                    $t.find('tbody tr:lt(3)').each(function () {
                        a += $(this).height();
                    });

                    // Set fail safe limit (last three row might be too tall)
                    // Set arbitrary limit at 0.25 of viewport height, or you can use an arbitrary pixel value
                    if (a > $w.height() * 0.25) {
                        a = $w.height() * 0.25;
                    }
                    // Add the height of sticky header
                    a += $stickyHead.height();
                    return a;
                };

            setWidths();

            $t.parent('.sticky-wrap').scroll($.throttle(250, function () {
                repositionStickyHead();
                repositionStickyCol();
            }));

            $w
                .load(setWidths)
                .resize($.debounce(250, function () {
                    setWidths();
                    repositionStickyHead();
                    repositionStickyCol();
                }))
                .scroll($.throttle(250, repositionStickyHead));
        }
    });
}